#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>
#include <math.h>

//Global Variables
int quick_single_thread[1024][1024];
int quick_multi_thread2[1024][1024];
int quick_multi_thread4[1024][1024];
int quick_multi_thread8[1024][1024];
int quick_multi_thread16[1024][1024];
int sorted_array[1024][1024];
int size[1024];

int **arraytable;	//Keeps track of all merges... arraytable[1022] is a pointer to the final 1,000,000 integer array.

int **merge2, **merge4, **merge8, **merge16;

//Structures
typedef struct _startend
{
	int start;
	int end;
	int thread_no;
	int thread_id;
}startend;

typedef struct _mergeStruct
{
	int start;
	int end;
	int thread_no;
	int thread_id;
	int*** array_address;
}mergeStruct;

typedef struct _timeing
{
	float quick_time;
	float quick2_time;
	float quick4_time;
	float quick8_time;
	float quick16_time;
	float merge_time;
	float merge2_time;
	float merge4_time;
	float merge8_time;
	float merge16_time;
}timing;

typedef struct _custom
{
	int thread_no;
	int thread_id;
	int result;
	int first;
	int second;
}custom;

//readArray.c
int readArray(int array1[1024][1024]);

//getTime.c
inline float getTime();

//quicksort.c
//int quick_sort(int a[1024][1024], int first, int last, int index);
int quick_sort(int a[1024][1024], int first, int last, int index);
int partition(int a[1024][1024], int first, int last, int index);

//Thread.c
void *quicksort_thread(void *param);
void run_quicksort_multithread(int thread_no);
void *custom_merge(void* param);
void *mergesort_thread(void *param);
int** run_mergesort_multithread(int thread_no);



//mergesort.c
int* merge_arrays(int a[1024], int b[], int n1, int n2);
int** merge(int a[1024][1024], int start, int end, int numrow);
int** merge_thread(int a[1024][1024], int*** tableaddress, int start, int end, int numrow);
int power(int a, int b);

//freemanager.c
void free_manager();

//checkSort.c
int check_sort_rows(int array[1024][1024]);
int check_sort_row(int *c);

//printresult.c
void print_to_file(timing* temp);
void print_result(timing* times);

